#!/usr/bin/python
# coding=utf-8

import os
import sys
import shutil
import glob
import xml.etree.cElementTree as ET
from xml.dom.minidom import parse
import traceback
import re

argv_len = 0

id_list = []
string_list = []
id_list_ok = []
layout_list_ok = []
drawable_list_ok = []
string_list_ok = []
big_res = ''
small_res = ''
smali_r_root_path = ''
public_xml = ''
public_name_list = []
layout_max_id = int('0x00000000', 16);
id_max_id = int('0x00000000', 16);
drawable_max_id = int('0x00000000', 16);
string_max_id = int('0x00000000', 16);

add_res_all = []


def main():
    global id_list_ok
    global layout_list_ok
    global drawable_list_ok
    global string_list_ok
    global big_res
    global small_res
    global public_xml
    global smali_r_root_path
    
    small_res = sys.argv[1]
    big_res = sys.argv[2]
    smali_r_root_path = sys.argv[3]
    if small_res[-1] == '\\':
        small_res = small_res[0:-3]
    elif small_res[-1] == '/':
        small_res = small_res[0:-2]
    if big_res[-1] == '\\':
        big_res = big_res[0:-3]
    elif big_res[-1] == '/':
        big_res = small_res[0:-2]
    if smali_r_root_path[-1] == '\\':
        smali_r_root_path = smali_r_root_path[0:-3]
    elif smali_r_root_path[-1] == '/':
        smali_r_root_path = smali_r_root_path[0:-2]    
    small_res_layout = small_res+'\\'+'layout'
    small_res_layout_xml_list = glob.glob(small_res_layout+'\\*.xml')
    
    small_res_drawable = small_res+'\\'+'drawable'
    small_res_drawable_list = os.listdir(small_res_drawable)
    
    small_res_values = glob.glob(small_res+'\\values-zh\\*.xml')
    for item in small_res_values:
        dom = parse(open(item))
        get_string_list(dom)
#        string_list_tmp = sorted(set(string_list),key=string_list.index)
        string_list_ok.extend(string_list)
    for name in small_res_drawable_list:
        pos = name.rfind('.')
        if pos != -1:
            drawable_list_ok.append(name[0:pos])
        else:
            drawable_list_ok.append(name)
    for xml_item in small_res_layout_xml_list:
        dom = parse(open(xml_item))
        layout_list_ok.append(os.path.basename(xml_item).replace('.xml', ''))
        k = 0
        get_id_list(dom)
#        id_list_tmp = sorted(set(id_list),key=id_list.index)
        id_list_ok.extend(id_list)
#    id_list_ok = sorted(set(id_list_ok),key=id_list_ok.index)
    id_list_ok = sorted(set(id_list_ok),key=id_list_ok.index)
    string_list_ok = sorted(set(string_list_ok),key=string_list_ok.index)
    drawable_list_ok = sorted(set(drawable_list_ok),key=drawable_list_ok.index)
    layout_list_ok = sorted(set(layout_list_ok),key=layout_list_ok.index)
#    {}.fromkeys(id_list_ok).keys()  
#    {}.fromkeys(string_list_ok).keys()  
#    {}.fromkeys(drawable_list_ok).keys()  
#    {}.fromkeys(layout_list_ok).keys()  
#    print(id_list_ok)
#    print('----------------------------')
#    print(layout_list_ok)
#    print('----------------------------')
#    print(drawable_list_ok)
#    print('----------------------------')
#    print(string_list_ok)
#    print('----------------------------')
    print('id adding...')
    ids_xml = big_res + '/' + 'res/values/ids.xml'
    public_xml = big_res + '/' + 'res/values/public.xml'
    make_public_info(public_xml)
    add_ids(ids_xml)
    add_layout(small_res_layout_xml_list)
    add_drawable(small_res_drawable_list)
    add_string()
    make_res_smali()

def make_res_smali():  
    global add_res_all
    global smali_r_root_path
    
    
    smali_r_file_id = smali_r_root_path+'\\R$id.smali'
    smali_r_file_open_id = open(smali_r_file_id, "r+")
    smali_r_file_open_con_id = smali_r_file_open_id.readlines()
    
    smali_r_file_string = smali_r_root_path+'\\R$string.smali'
    smali_r_file_open_string = open(smali_r_file_string, "r+")
    smali_r_file_open_con_string = smali_r_file_open_string.readlines()
    
    smali_r_file_drawable = smali_r_root_path+'\\R$drawable.smali'
    smali_r_file_open_drawable = open(smali_r_file_drawable, "r+")
    smali_r_file_open_con_drawable = smali_r_file_open_drawable.readlines()
    
    smali_r_file_layout = smali_r_root_path+'\\R$layout.smali'
    smali_r_file_open_layout = open(smali_r_file_layout, "r+")
    smali_r_file_open_con_layout = smali_r_file_open_layout.readlines()    
    
#    print(smali_r_file_open_con)
    smali_r_str_id = ''
    smali_r_str_string = ''
    smali_r_str_layout = ''
    smali_r_str_drawable = ''
    
    #id
    for i in add_res_all:
        if i['type'] == 'id':
            smali_r_str_id = smali_r_str_id + ".field public static final "+i['name']+":I = "+i['id']+"\n"
    tmp = ''
    for i in smali_r_file_open_con_id:
        regex = ur"# direct methods"        
        if re.search(regex, i):
            tmp = tmp + smali_r_str_id + i
        else:
            tmp = tmp + i
    if tmp != '':
        smali_r_file_open_id.seek(0)
        smali_r_file_open_id.write(tmp)
    
    #string
    for i in add_res_all:
        if i['type'] == 'string':
            smali_r_str_string = smali_r_str_string + ".field public static final "+i['name']+":I = "+i['id']+"\n"
    tmp = ''
    for i in smali_r_file_open_con_string:
        regex = ur"# direct methods"        
        if re.search(regex, i):
            tmp = tmp + smali_r_str_string + i
        else:
            tmp = tmp + i
    if tmp != '':
        smali_r_file_open_string.seek(0)
        smali_r_file_open_string.write(tmp)    
        
    #drawable
    for i in add_res_all:
        if i['type'] == 'drawable':
            smali_r_str_drawable = smali_r_str_drawable + ".field public static final "+i['name']+":I = "+i['id']+"\n"
    tmp = ''
    for i in smali_r_file_open_con_drawable:
        regex = ur"# direct methods"        
        if re.search(regex, i):
            tmp = tmp + smali_r_str_drawable + i
        else:
            tmp = tmp + i
    if tmp != '':
        smali_r_file_open_drawable.seek(0)
        smali_r_file_open_drawable.write(tmp)
    
    #layout
    for i in add_res_all:
        if i['type'] == 'layout':
            smali_r_str_layout = smali_r_str_layout + ".field public static final "+i['name']+":I = "+i['id']+"\n"
    tmp = ''
    for i in smali_r_file_open_con_layout:
        regex = ur"# direct methods"        
        if re.search(regex, i):
            tmp = tmp + smali_r_str_layout + i
        else:
            tmp = tmp + i
    if tmp != '':
        smali_r_file_open_layout.seek(0)
        smali_r_file_open_layout.write(tmp)
    
    
#    print(smali_r_str)



    
def trace_back():  
    try:  
        return traceback.print_exc()  
    except:  
        return ''

def make_public_info(public_xml):
    global public_name_list
    global layout_max_id
    global id_max_id
    global drawable_max_id
    global string_max_id
    dom = parse(open(public_xml))
    tmp = dom.getElementsByTagName('resources')[0]
    for i in tmp.childNodes:
        if i.nodeName != '#text' and i.getAttribute('name') != '' and i.getAttribute('type') != '':
            tmp_name = i.getAttribute('type')+'::'+i.getAttribute('name')
            if tmp_name not in public_name_list:
                public_name_list.append(tmp_name)
            tmp_id = int(i.getAttribute('id'), 16)
            if i.getAttribute('type') == 'layout' and tmp_id > layout_max_id:
                layout_max_id = tmp_id
            elif i.getAttribute('type') == 'id' and tmp_id > id_max_id:
                id_max_id = tmp_id           
            elif i.getAttribute('type') == 'drawable' and tmp_id > drawable_max_id:
                drawable_max_id = tmp_id      
            elif i.getAttribute('type') == 'string' and tmp_id > string_max_id:
                string_max_id = tmp_id
#    print(public_name_list)
#    exit()    
    
def add_string():
    global string_list_ok
    global big_res
    global small_res
    global public_xml
    global string_max_id
    global add_res_all
    global public_name_list
    ##没有拷贝string值
    #向public.xml加入
    dom = parse(open(public_xml, "r"))
    tmp = dom.getElementsByTagName('resources')[0]
    for i in string_list_ok:
        if ('string::'+i) in public_name_list:
            continue
        string_max_id = string_max_id+1
        iNode = dom.createElement("public")
        iNode.setAttribute("type", "string")
        iNode.setAttribute("name", i)
        iNode.setAttribute("id", hex(string_max_id))
        tmp.appendChild(iNode)
        tmp9 = {}
        tmp9['type'] = 'string'
        tmp9['name'] = i
        tmp9['id'] = hex(string_max_id)
        add_res_all.append(tmp9)
    dom.writexml(open(public_xml, "w"), "", "", "", "utf-8")
    
def add_ids(ids_xml):
    global id_list_ok
    global public_xml
    global id_max_id
    global add_res_all
    global public_name_list
    try:
        dom = parse(open(ids_xml, "r"))
        tmp = dom.getElementsByTagName('resources')[0]
        tmp_list = []
        for i in tmp.childNodes:
            if i.nodeName != '#text' and i.getAttribute('name') != '':
                tmp_list.append(i.getAttribute('name'))
        for i in id_list_ok:
            ##判断该id是否存在
            if i in tmp_list:
                continue
            iNode = dom.createElement("item")
            iNode.setAttribute("type", "id")
            iNode.setAttribute("name", i)
            textNode = dom.createTextNode("false")
            iNode.appendChild(textNode)
            tmp.appendChild(iNode)
        dom.writexml(open(ids_xml, "w"), "", "", "", "utf-8")
        
        #向public.xml加入
        #    print(public_xml)
        dom = parse(open(public_xml, "r"))
        tmp = dom.getElementsByTagName('resources')[0]    
        for i in id_list_ok:
            if ('id::'+i) in public_name_list:
                continue
            id_max_id = id_max_id+1
            iNode = dom.createElement("public")
            iNode.setAttribute("type", "id")
            iNode.setAttribute("name", i)
            iNode.setAttribute("id", hex(id_max_id))
            tmp.appendChild(iNode)
            tmp9 = {}
            tmp9['type'] = 'id'
            tmp9['name'] = i
            tmp9['id'] = hex(id_max_id)
            add_res_all.append(tmp9)
        dom.writexml(open(public_xml, "w"), "", "", "", "utf-8")
    except:
        print trace_back()
        
def add_drawable(small_res_drawable_list):
    global drawable_list_ok
    global big_res
    global small_res
    global public_xml
    global drawable_max_id
    global add_res_all
    global public_name_list
    #复制文件
    for i in small_res_drawable_list:
        tmp = big_res+'\\res\\drawable\\'+os.path.basename(i)
        if not os.path.exists(tmp):
            tmp2 = small_res+'\\drawable\\'+i
            shutil.copyfile(tmp2, tmp)
            print(i+'--ok~')
    #向public.xml加入
    dom = parse(open(public_xml, "r"))
    tmp = dom.getElementsByTagName('resources')[0]    
    for i in drawable_list_ok:
        if ('drawable::'+i) in public_name_list:
            continue
        drawable_max_id = drawable_max_id+1
        iNode = dom.createElement("public")
        iNode.setAttribute("type", "drawable")
        iNode.setAttribute("name", i)
        iNode.setAttribute("id", hex(drawable_max_id))
        tmp.appendChild(iNode)
        tmp9 = {}
        tmp9['type'] = 'drawable'
        tmp9['name'] = i
        tmp9['id'] = hex(drawable_max_id)
        add_res_all.append(tmp9)        
    dom.writexml(open(public_xml, "w"), "", "", "", "utf-8")
    
def add_layout(small_res_layout_xml_list):
    global layout_list_ok
    global big_res
    global small_res
    global public_xml
    global layout_max_id
    global add_res_all
    global public_name_list
    #复制文件
    for i in small_res_layout_xml_list:
        tmp = big_res+'\\res\\layout\\'+os.path.basename(i)
        if not os.path.exists(tmp):
            shutil.copyfile(i, tmp)
            print(i+'--ok~')
    #向public.xml加入
#    print(public_xml)
    dom = parse(open(public_xml, "r"))
    tmp = dom.getElementsByTagName('resources')[0]    
    for i in layout_list_ok:
        if ('layout::'+i) in public_name_list:
            continue
        layout_max_id = layout_max_id+1
        iNode = dom.createElement("public")
        iNode.setAttribute("type", "layout")
        iNode.setAttribute("name", i)
        iNode.setAttribute("id", hex(layout_max_id))
        tmp.appendChild(iNode)
        tmp9 = {}
        tmp9['type'] = 'layout'
        tmp9['name'] = i
        tmp9['id'] = hex(layout_max_id)
        add_res_all.append(tmp9)
    dom.writexml(open(public_xml, "w"), "", "", "", "utf-8")        
    
def get_id_list(dom):
    for node in dom.childNodes:
#        print(len(node.childNodes))
#        print(node.nodeName)
        if node.nodeName != '#text' and node.getAttribute('android:id') != '':
            id_list.append(node.getAttribute('android:id').split('/')[-1])
        if len(node.childNodes) > 1:
            get_id_list(node)

def get_string_list(dom):
    tmp = dom.getElementsByTagName('resources')[0].getElementsByTagName('string')
    for item in tmp:
        string_list.append(item.getAttribute('name'))

if __name__ == '__main__':
    print sys.argv
    argv_len = len(sys.argv)
    if argv_len >= 2 and sys.argv[1] == '-h':
        print ("Usage:python addto_res.py from(F:\workbench\umeng_res) to(F:\workbench\hzwbz) R_path(F:\workbench\hzwbz\smali\org\bingluo\onepiece\wallpaper)")
        exit(1)    
    if argv_len < 4:
        print ('need 4 argv.')
        exit(1)
    if not (os.path.isdir(sys.argv[1]) and os.path.isdir(sys.argv[2]) and os.path.isdir(sys.argv[3])):
        print ('need is dir.')
        exit(1)
    main()
